package de.fstyle.android.worldcanvas;

import java.io.IOException;

import org.apache.http.client.ClientProtocolException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import de.fstyle.android.worldcanvas.fragments.ColorFragment;
import de.fstyle.android.worldcanvas.util.ColorUtils;
import de.fstyle.android.worldcanvas.util.HttpUtils;

public class ColorUpdateRunnable implements Runnable {

	public static final long DEFAULT_UPDATE_INTERVAL = 5 * 1000; // milliseconds
	public static final String LOG_TAG = "get_color";

	private ColorFragment fragment;
	private LocationWrapper locationWrapper;
	private boolean stop = false;
	private long interval;
	private long delay;
	
	public ColorUpdateRunnable(
			ColorFragment fragment,
			LocationWrapper locationWrapper,
			long interval,
			long delay) {
		
		this.fragment = fragment;
		this.locationWrapper = locationWrapper;
		this.interval = interval;
		this.delay = delay;
	}
	
	public void stop() {
		Log.d(LOG_TAG, "request color request stop");
		this.stop = true;
		Log.d(LOG_TAG, "stop: " + this.stop);
	}
	
	public boolean isActive() {
		return !this.stop;
	}
	
	@Override
	public void run() {
		Handler handler = new Handler(Looper.getMainLooper());
		
		while(!this.stop) {

			// delay
			
			if (this.delay > 0) {
				Log.d(LOG_TAG, "delaying for: " + this.delay + "ms");
				try {
					Thread.sleep(this.delay);
				} catch (InterruptedException e) {
					Log.d(LOG_TAG, "error", e);
				}
				
				// reset delay
				this.delay = -1;
			}
			
			// retrieve color
			
			Log.d(LOG_TAG, "retrieving color: " + this.stop);
			
			// check network connection
			Log.d(LOG_TAG, "check if online");
			
			handler.post(new Runnable() {
				@Override
				public void run() {
					ColorUpdateRunnable.this.fragment.setInternetAvailable(
							ColorUpdateRunnable.this.fragment.isOnline());
				}
			});
			
			if (!this.fragment.isOnline()) {

				Log.d(LOG_TAG, "not online");
				
//				handler.post(new Runnable() {
//					@Override
//					public void run() {
//						
//						if (ColorUpdateRunnable.this.fragment.getActivity() != null) {
//							Toast toast = Toast.makeText(
//									ColorUpdateRunnable.this.fragment.getActivity(), 
//									"No internet connection.\n" +
//											"Local color could not be loaded.", 
//									Toast.LENGTH_SHORT);
//							toast.show();
//						}
//					}
//				});
				
			// try to get color if location fix is given
			} else if (this.locationWrapper.getLocation() != null) {
			
				handler.post(new Runnable() {
					@Override
					public void run() {
						ColorUpdateRunnable.this.fragment.setLocationAvailable(true);
					}
				});
				
				Log.d(LOG_TAG, "online");
				Log.d(LOG_TAG, "location fix found");
				
				Integer color = null;
				try {
					Log.d(LOG_TAG, "getting color");
					JSONArray jsonObject = HttpUtils.get(this.locationWrapper.getLocation());
					if (jsonObject.length() > 0) {
						Log.d(LOG_TAG, "packet received; trying to parse color");
						JSONObject data = jsonObject.getJSONObject(0).getJSONObject("data");
						String colorObjectString = data.getString("content");
						Log.d(LOG_TAG, colorObjectString);
						
						JSONObject colorObject = new JSONObject(colorObjectString);
						color = colorObject.getInt(ColorUtils.COLOR_ATTRIBUTE);
						Log.d(LOG_TAG, "parsed color: " + color);
						
						handler.post(new Runnable() {
							@Override
							public void run() {
								ColorUpdateRunnable.this.fragment.setColorAttached(true);
							}
						});
					} else {
						Log.d(LOG_TAG, "no packet for this area");
//						handler.post(new Runnable() {
//							@Override
//							public void run() {
//								if (ColorUpdateRunnable.this.fragment.getActivity() != null) {
//									Toast toast = Toast.makeText(
//											ColorUpdateRunnable.this.fragment.getActivity(), 
//											"No color attached to this place yet.\n" +
//											"It's your chance, be the first!", 
//											Toast.LENGTH_SHORT);
//									toast.show();
//								}
//							}
//						});
						
						handler.post(new Runnable() {
							@Override
							public void run() {
								ColorUpdateRunnable.this.fragment.setColorAttached(false);
							}
						});
						
						color = Color.WHITE; // set color white for empty locations
					}
				} catch (ClientProtocolException e) {
					Log.d(LOG_TAG, "error", e);
				} catch (JSONException e) {
					Log.d(LOG_TAG, "error", e);
				} catch (IOException e) {
					Log.d(LOG_TAG, "error", e);
				}
				
				if (!this.stop && color != null) {
					Log.d(LOG_TAG, "setting background");
					handler.post(new SetBackgroundColor(this.fragment, color));
				}
				
			// no location fix, no color
			} else {
				
				Log.d(LOG_TAG, "no location fix");
				
				handler.post(new Runnable() {
					@Override
					public void run() {
						ColorUpdateRunnable.this.fragment.setLocationAvailable(false);
					}
				});
				
//				handler.post(new Runnable() {
//					@Override
//					public void run() {
//						if (ColorUpdateRunnable.this.fragment.getActivity() != null) {
//							Toast toast = Toast.makeText(
//									ColorUpdateRunnable.this.fragment.getActivity(), 
//									"No location fix.\n" +
//									"Local color could not be loaded.", 
//									Toast.LENGTH_SHORT);
//							toast.show();
//						}
//					}
//				});
			}
			
			try {
				Thread.sleep(this.interval);
			} catch (InterruptedException e) {
				Log.d(LOG_TAG, "error", e);
			}
		}
		
		Log.d(LOG_TAG, "stopped color update");
	}
	
	public void setInterval(long interval) {
		this.interval = interval;
	}
	
	public void setDelay(long delay) {
		this.delay = delay;
	}
	
	public static final class SetBackgroundColor implements Runnable {

		private ColorFragment view;
		private Integer color;
		
		public SetBackgroundColor(ColorFragment view, Integer color) {
			this.view = view;
			this.color = color;
		}

		@Override
		public void run() {
			this.view.setCurrentColor(this.color);
		}
	}

}
